import axios, { AxiosError } from 'axios';
import { Toast } from 'antd-mobile';
import { getToken, hasToken } from './tokens';
import history from './history';
import store from '../store';
import { gettingToken, removeToken } from '@/store/actions/login';
//封装axios
const instance = axios.create({
  baseURL: process.env.REACT_APP_BASE_URL,
  timeout: 5000,
});

//请求拦截器
instance.interceptors.request.use(
  (config) => {
    // 在发送请求之前做什么
    if (hasToken()) {
      config.headers!.Authorization = `Bearer ${getToken().token}`;
    }
    return config;
  },
  (error) => {
    //对请求错误做些什么
    return Promise.reject(error);
  }
);

//响应拦截器
instance.interceptors.response.use(
  (response) => {
    //对请求数据做些什么(去壳????)
    return response; //这里不return,则请求获取不到数据
  },
  async (error: AxiosError<{ message: string }>) => {
    //对请求错误做些什么
    if (!error.response) {
      Toast.show({
        content: '服务器繁忙,请稍后重试',
      });
      return Promise.reject(error);
    }
    //响应错误401,也就是没有token,或者是token错误,或者是token过期
    //1.先判断是否有token,如果没有token,就跳转到登录页面(虽然封装的路由组件处理了没有token跳转登录页面,但是这里还是需要判断,增强用户体验)
    //2.有token,但是token过期了,发请求,刷新token
    //  2.1.token刷新成功了,重新在发请求,获取数据
    // 2.2.token刷新失败了,跳转到登录页面,且清除token信息
    if (error.response.status === 401) {
      const token = getToken();
      if (token.token && token.refresh_token) {
        //有token,重新发请求刷新token==>注意这里发请求不能使用封装的,不然会死循环
        try {
          const { data } = await axios.put(
            `${process.env.REACT_APP_BASE_URL}authorizations`,
            null,
            {
              headers: { Authorization: `Bearer ${token.refresh_token}` },
            }
          );
          // console.log('token刷新成功了');====>重新发请求,获取数据
          //刷新成功,但是会在页面提示,需要刷新2次,用户会有感,因此需要下面直接在刷新一次
          store.dispatch(
            gettingToken({
              token: data.data.token,
              refresh_token: token.refresh_token,
            })
          );
          //自动刷新页面一次,也就是获取用户信息,并获取数据,使用封装的hooks函数,一步完成
          // 这里应该是用新的token,替换之前添加到请求拦截器中错误的token
          console.log(error.config);
          return instance(error.config);
        } catch {
          //此处是监听刷新token失败,也就是refresh_token失效了
          store.dispatch(removeToken());
          history.replace('/login', { from: history.location.pathname });
        }
      } else {
        //没有token,给个提示消息,跳转登录页面
        history.replace('/login');
      }
    }
    Toast.show(error.response.data.message);
    return Promise.reject(error);
  }
);

//导出
export default instance;
